// src/utils/scanner.js

const { generateToken } = require('./jwt');
const crypto = require('crypto');

class ScannerService {
  constructor(env) {
    this.env = env;
  }

  // 生成新的扫码场景
  async createScene(appId) {
    const sceneId = crypto.randomUUID();
    const scene = {
      sceneId,
      appId,
      status: 'pending',
      createTime: Date.now(),
      expireTime: Date.now() + 5 * 60 * 1000 // 5分钟过期
    };

    await this.env.SCAN_KV.put(`scene:${sceneId}`, JSON.stringify(scene), {
      expirationTtl: 300 // 5分钟
    });

    return sceneId;
  }

  // 获取场景信息
  async getSceneInfo(sceneId) {
    const scene = await this.env.SCAN_KV.get(`scene:${sceneId}`, { type: 'json' });
    if (!scene) {
      throw new Error('场景不存在或已过期');
    }
    return scene;
  }

  // 更新场景状态
  async updateSceneStatus(sceneId, status) {
    const scene = await this.getSceneInfo(sceneId);
    scene.status = status;
    
    await this.env.SCAN_KV.put(`scene:${sceneId}`, JSON.stringify(scene), {
      expirationTtl: Math.max(1, Math.floor((scene.expireTime - Date.now()) / 1000))
    });

    return scene;
  }

  // 处理扫码授权
  async handleAuthorization(sceneId, accountId) {
    const scene = await this.getSceneInfo(sceneId);
    
    if (scene.status !== 'pending') {
      throw new Error('场景状态无效');
    }

    if (Date.now() > scene.expireTime) {
      throw new Error('场景已过期');
    }

    // 更新场景状态
    await this.updateSceneStatus(sceneId, 'authorized');

    // 生成授权token
    const token = generateToken(
      { sub: accountId },
      this.env.JWT_SECRET,
      { expiresIn: '24h' }
    );

    // 存储授权信息
    await this.env.AUTH_KV.put(`auth:${sceneId}`, JSON.stringify({
      accountId,
      token,
      createTime: Date.now()
    }), {
      expirationTtl: 86400 // 24小时
    });

    return { token };
  }

  // 取消授权
  async cancelAuthorization(sceneId) {
    const scene = await this.getSceneInfo(sceneId);
    await this.updateSceneStatus(sceneId, 'cancelled');
    return true;
  }

  // 检查场景是否过期
  isSceneExpired(scene) {
    return Date.now() > scene.expireTime;
  }
}

module.exports = ScannerService;
